#! /usr/bin/env python
#coding=utf-8
from google.appengine.api import users
import web

import models
from api import dispatcher
import utils
from utils import send_to
import forms

import widgets

template_env = dict(get_blog_config=models.get_blog_config,
                    get_user=users.get_current_user,
                    logout_url=users.create_logout_url('/'),
                )
render = utils.render('views', template_env)


def check_login(func):
    def wrapper(*args, **kwargs):
        u = users.get_current_user()
        if not u:
            raise web.seeother(users.create_login_url(web.ctx.path))
        elif not users.is_current_user_admin():
            raise web.seeother(users.create_login_url('/admin'))
        else:
            return func(*args, **kwargs)
    wrapper.__name__ = func.__name__
    return wrapper

#################################


class Home(object):

    @check_login
    def GET(self):
        raise web.seeother('/admin/entry')


class EntryManager(object):

    @check_login
    @send_to(render, 'entry_mg.html')
    def GET(self, start_index=None):
        config = models.get_blog_config()
        entries, prev, next = models.Entry.get_items(start_index, config.entries_per_page, True)
        links = utils.get_paging_links(entries, prev, next, start_index)
        return dict(title='Entries',
                    current_tab='entry',
                    entries=entries,
                    links=links,
                    )

    @check_login
    def POST(self, start_index=None):
        i = web.input(selected=[])
        indices = map(utils.safeint, i.get('selected', []))
        
        for index in indices:
            models.Entry.del_by_index(index)

        raise web.seeother(web.ctx.path)


class EntryEditor(object):

    @check_login
    @send_to(render, 'edit.html')
    def GET(self, action, index='0'):
        if action == 'new':
            return dict(entry_form=forms.entry_form(),
                        title='New Entry')
        elif action == 'edit':
            index = utils.safeint(index)
            entry = models.Entry.get_by_index(index)
            if entry:
                return dict(entry_form=forms.entry_form(entry),
                            title='Edit Entry')
        raise web.seeother('/admin/entry')

    @check_login
    @send_to(render, 'edit.html')
    def POST(self, action, index='0'):
        entry_form=forms.entry_form()
        i = web.input()

        if action == 'new':
            if not entry_form.validates(i):
                return dict(entry_form=entry_form,
                            title='Edit Entry')
            models.Entry.new(author=users.get_current_user(),
                            title=i.title, content=i.content, tags=i.tags, entype=i.entype)

        elif action == 'edit':
            entry = models.Entry.get_by_index(utils.safeint(index))
            if entry:
                if not entry_form.validates(i):
                    return dict(entry_form=entry_form,
                                title='Edit Entry')
                entry.edit(author=users.get_current_user(),
                                title=i.title, content=i.content, tags=i.tags, entype=i.entype)

        raise web.seeother('/admin/entry')


class CommentManager(object):

    @check_login
    @send_to(render, 'comment.html')
    def GET(self, start_index=None):
        config = models.get_blog_config()
        comments, prev, next = models.Comment.get_items(start_index, config.entries_per_page, True)
        links = utils.get_paging_links(comments, prev, next, start_index)

        return dict(title='Comments',
                    current_tab='comment',
                    comments=comments,
                    links=links,
                    )

    @check_login
    @send_to(render, 'comment.html')
    def POST(self, start_index=None):
        i = web.input(selected=[])
        indices = map(utils.safeint, i.get('selected', []))

        for index in indices:
            models.Comment.del_by_index(index)

        raise web.seeother(web.ctx.path)


class PrefEditor(object):

    @check_login
    @send_to(render, 'pref.html')
    def GET(self):
        pref_form = forms.pref_form(models.get_blog_config())
        u = users.get_current_user()
        return dict(title='Preference',
                    current_tab='pref',
                    form=pref_form,
                    rpc_email=u.email(),
                    rpc_passwd=models.RpcUser.get_passwd(u))


    @check_login
    @send_to(render, 'pref.html')
    def POST(self):
        u = users.get_current_user()
        pref_form = forms.pref_form(models.get_blog_config())
        i = web.input()

        if not pref_form.validates(i):
            return dict(title='Preference',
                    current_tab='pref',
                    form=pref_form,
                    rpc_email=u.email(),
                    rpc_passwd=models.RpcUser.get_passwd(u))

        subtitle = i.get('subtitle', '')
        models.get_blog_config().edit(title=i.title,
                            subtitle=subtitle,
                            theme_name=i.theme,
                            entries_per_page=utils.safeint(i.entries_per_page))

        raise web.seeother('/admin/pref')


class RpcHandler(object):

    def GET(self):
        return '<h1>POST only. -_____________-</h1>'

    def POST(self):
        response = dispatcher._marshaled_dispatch(web.webapi.data())
        web.header('Content-length', str(len(response)))
        return response


class RpcManager(object):

    @check_login
    def GET(self):
        u = users.get_current_user()
        models.RpcUser.regenerate_password(u)
        raise web.seeother('/admin/pref')


#todo:
#paging
class WidgetManager(object):

    @check_login
    @send_to(render, 'widgets.html')
    def GET(self, action='', fullname=''):
        #return widgets.log.getvalue()
        if not (action or fullname):
            return dict(widgets=widgets.get_widgets(),
                        title='Widgets',
                        current_tab='widget')
        widget = widgets.get_widget_by_name(fullname)
        if action == 'enable':
            widget.enable()
        if action == 'disable':
            widget.disable()
        if action == 'customize':
            return (dict(customize_form=widget.customize_form(), widget=widget,
                        title='Customize Widget:%s' % widget.fullname(),
                        current_tab='widget'), 'widget_customize.html')
        raise web.seeother('/admin/widget')


    @check_login
    @send_to(render, 'widget_customize.html')
    def POST(self, action='', fullname=''):
        if not (action or fullname):
            raise web.seeother('/admin/widget')
        if action == 'customize':
            widget = widgets.get_widget_by_name(fullname)
            if widget:
                cform = widget.customize_form()
                i = web.input()

                if cform and not cform.validates(i):
                    return dict(customize_form=cform, title='Customize Widget:%s' % widget.fullname(),
                                current_tab='widget')
                widget.set_data(i)
        raise web.seeother('/admin/widget')


def _update_entype():
    entries = models.db.GqlQuery("SELECT * FROM Entry")
    for e in entries:
        if e.entype != 'page':
            e.entype = 'post'
            e.put()


class Updater(object):

    def GET(self):
        #run only once
        current_version = 1.022  #this value is updated manually
        config = models.get_blog_config()

        if config.version < current_version:
            #add ur own updating code here.
            _update_entype()
            config = models.get_blog_config()
            config.edit(version=current_version)
        raise web.seeother('/admin/entry')


class Test(object):

    @check_login
    def GET(self):
        u = users.get_current_user()
        for i in xrange(20):
            e = models.Entry.new(author=u,
                             title='This is Post %d Again' % i, tags='different', entype='post',
                             content='Fuck You and Fuck You!!!')
            models.Comment.new(entry=e, author="WTF", email="iwinux@gmail.com",
                               site="http://ether.appspot.com")
        # for i in xrange(20):
            # models.Entry.new(author=u,
            #                  title='Page %d' % i, tags='omg', entype='page',
            #                  content='Fuck You and Fuck You!!!')

        raise web.seeother('/admin/entry')
